package com.itheima.a20.test;

import com.itheima.a20.MyRequestMappingHandlerAdapter;
import com.itheima.a20.Token;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import java.util.List;

@Configuration
@ComponentScan
@PropertySource("classpath:application.properties")
@EnableConfigurationProperties({WebMvcProperties.class, ServerProperties.class})
public class CajTest20 {
    public static void main(String[] args) throws Exception {
        ApplicationContext contxt = new AnnotationConfigServletWebServerApplicationContext(CajTest20.class);
        RequestMappingHandlerMapping mapping = contxt.getBean(RequestMappingHandlerMapping.class);

        mapping.getHandlerMethods().forEach((k,v)->{
            System.out.println(k + "------" + v);
        });

        MyRequestMappingHandlerAdapter adaptor = contxt.getBean(MyRequestMappingHandlerAdapter.class);
        System.out.println(adaptor.getArgumentResolvers());
        System.out.println(adaptor.getArgumentResolvers());
        System.out.println(adaptor.getCustomArgumentResolvers());
        System.out.println(adaptor.getCustomReturnValueHandlers());
        System.out.println(adaptor.getInitBinderArgumentResolvers());

        //构建请求对象
        MockHttpServletResponse response = new MockHttpServletResponse();
        MockHttpServletRequest request = new MockHttpServletRequest("PUT", "/test3");
        request.setParameter("name", "张三");
        request.addHeader("token", "某个令牌");


        HandlerExecutionChain handler = mapping.getHandler(request);

        adaptor.invokeHandlerMethod(request, response,(HandlerMethod) handler.getHandler());

    }


    @Bean
    public TomcatServletWebServerFactory tomcatServletWebServerFactory(){
        return new TomcatServletWebServerFactory();
    }

    @Bean
    public DispatcherServlet dispatcherServlet(){
        return new DispatcherServlet();
    }

    @Bean
    public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(
            DispatcherServlet dispatcherServlet, WebMvcProperties webMvcProperties) {
        DispatcherServletRegistrationBean registrationBean = new DispatcherServletRegistrationBean(dispatcherServlet, "/");
        registrationBean.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
        return registrationBean;
    }
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping(){
        return new RequestMappingHandlerMapping();
    }

    @Bean
    public MyRequestMappingHandlerAdapter myRequestMappingHandlerAdapter(){
        MyRequestMappingHandlerAdapter adaptor = new MyRequestMappingHandlerAdapter();


        adaptor.setCustomArgumentResolvers(List.of(
                new TokenArgumentResolver()

        ));
        adaptor.setCustomReturnValueHandlers(List.of(
                new YmlHandlerMethodReturnValueHandler()

        ));

        return adaptor;
    }






    public static class TokenArgumentResolver implements HandlerMethodArgumentResolver , Ordered {

        @Override
        public boolean supportsParameter(MethodParameter parameter) {
            System.out.println("111111");
            Token token = parameter.getParameterAnnotation(Token.class);
            return token != null;
        }

        @Override
        public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
            String token = webRequest.getHeader("token");
            System.out.println(token + "======");
            return token;

        }

        @Override
        public int getOrder() {
            return -100;
        }
    }












}
